package com.nf.health.app.utils;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by Jason on 2016/7/7.
 */
public class CompareUtil {
    //sort 1正序 -1 倒序  filed 多字段排序
    public static <T> Comparator createComparator(int sort, String... filed) {
        return new ImComparator(sort, filed);
    }

    public static class ImComparator implements Comparator {
        int sort = 1;
        String[] filed;

        public ImComparator(int sort, String... filed) {
            this.sort = sort == -1 ? -1 : 1;
            this.filed = filed;
        }

        @Override
        public int compare(Object o1, Object o2) {
            int result = 0;
            for (String file : filed) {
                Object value1 =  invokeMethod(file, o1);
                Object value2 =  invokeMethod(file, o2);
                if (value1 == null || value2 == null) {
                    continue;
                }
                if (value1 instanceof Integer) { //Integer整数序排序
                    int v1 = Integer.valueOf(value1.toString());
                    int v2 = Integer.valueOf(value2.toString());
                    if (v1 == v2) continue;
                    if (sort == 1) {
                        return v1 - v2;
                    } else if (sort == -1) {
                        return v2 - v1;
                    }
                } else if (value1 instanceof Date) {  //Date类型排序
                    Date d1 = (Date) value1;
                    Date d2 = (Date) value2;
                    if (d1.compareTo(d2) == 0) continue;
                    if (sort == 1) {
                        return d1.compareTo(d2);
                    } else if (sort == -1) {
                        return d2.compareTo(d1);
                    }
                } else if (value1 instanceof Long) { //Long排序
                    long v1 = Long.valueOf(value1.toString());
                    long v2 = Long.valueOf(value2.toString());
                    if (v1 == v2) continue;
                    if (sort == 1) {
                        return v1 > v2 ? 1 : -1;
                    } else if (sort == -1) {
                        return v2 > v1 ? 1 : -1;
                    }
                } else if (value1 instanceof Double) { //Double排序
                    Double v1 = Double.valueOf(value1.toString());
                    Double v2 = Double.valueOf(value2.toString());
                    if (v1 == v2) continue;
                    if (sort == 1) {
                        return v1 > v2 ? 1 : -1;
                    } else if (sort == -1) {
                        return v2 > v1 ? 1 : -1;
                    }
                }

            }

            return result;
        }
    }



    //getMethod
    static public Object invokeMethod(String propertiesName, Object object) {
        try {
            if(object==null) return null;
            if (!propertiesName.contains(".")) {
                String methodName = "get"+getMethodName(propertiesName);
                Method method = object.getClass().getMethod(methodName);
                return method.invoke(object);
            }
            String methodName = "get"+getMethodName(propertiesName.substring(0,propertiesName.indexOf(".")));
            Method method = object.getClass().getMethod(methodName);
            return invokeMethod(propertiesName.substring(propertiesName.indexOf(".")+1), method.invoke(object));

        } catch (Exception e) {
            return null;
        }
    }

    private static String getMethodName(String fildeName) {
        byte[] items = fildeName.getBytes();
        items[0] = (byte) ((char) items[0] - 'a' + 'A');
        return new String(items);
    }

    /**
     * 使用 Map按key进行排序
     * @param map
     * @return
     */
    public static Map<String, Object> sortMapByKey(Map<String, Object> map) {
        if (map == null || map.isEmpty()) {
            return null;
        }

        Map<String, Object> sortMap = new TreeMap<String, Object>(
                new MapKeyComparator());

        sortMap.putAll(map);

        return sortMap;
    }
    public static ArrayList<String> sortMapByKeyList(HashMap<String, Object> map) {
        if (map == null || map.isEmpty()) {
            return null;
        }
        ArrayList<String> list = new ArrayList<>();
        Map<String, Object> sortMap = new TreeMap<String, Object>(new MapKeyComparator());
        sortMap.putAll(map);

        Iterator it = sortMap.keySet().iterator();
        while (it.hasNext()) {
            //it.next()得到的是key，tm.get(key)得到obj
            String ksy = it.next().toString();
             list.add(ksy);
        }
        return list;
    }
    static class MapKeyComparator implements Comparator<String>{

        @Override
        public int compare(String str1, String str2) {

            return str1.compareTo(str2);
        }
    }
    public static Map<String, Object> sortMapByKey2(Map<String, Object> oriMap) {
        if (oriMap == null || oriMap.isEmpty()) {
            return null;
        }
        Map<String, Object> sortedMap = new TreeMap<String, Object>(new Comparator<String>() {
            public int compare(String key1, String key2) {
                int intKey1 = 0, intKey2 = 0;
                try {
                    intKey1 = getInt(key1);
                    intKey2 = getInt(key2);
                } catch (Exception e) {
                    intKey1 = 0;
                    intKey2 = 0;
                }
                return intKey1 - intKey2;
            }});
        sortedMap.putAll(oriMap);
        return sortedMap;
    }

    private static  int getInt(String str) {
        int i = 0;
        try {
            Pattern p = Pattern.compile("^\\d+");
            Matcher m = p.matcher(str);
            if (m.find()) {
                i = Integer.valueOf(m.group());
            }
        } catch (NumberFormatException e) {
            e.printStackTrace();
        }
        return i;
    }
}
